home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
c
/
toollib
/
source
/
string.s
< prev
next >
Wrap
Text File
|
1995-12-30
|
21KB
|
395 lines
opt l+,o+,ow-
*
* string.s version 8.1 - © Copyright 1990 Jaba Development
*
* Author : Jan van den Baard
* Assembler : Devpac version 2.14
*
incdir 'sys:devpac_inc/'
include 'mymacros.i'
include 'exec/memory.i'
include 'exec/exec_lib.i'
include 'libraries/dos.i'
include 'libraries/dos_lib.i'
include 'tool.i'
xref DoFmt
xref DoBuf
xref CharRight
xref CharLeft
xref StrCpy
xref ToUpper
xref ToLower
xref StrLen
xref StrCmp
xref StriCmp
xref _DOSBase
xdef Format
xdef WriteFormat
xdef MatchPattern
xdef Isolate
xdef BstrToCstr
xdef GetDate
Format: movem.l a2-a3/a6,-(sp)
move.l a0,a3 ; buffer to a3
move.l a1,a0 ; format string to a0
move.l a2,a1 ; arguments (pointer!) to a1
move.l #DoBuf,a2 ; specal routine (support.s)
move.l (_SysBase).w,a6
libcall RawDoFmt ; format the output
movem.l (sp)+,a2-a3/a6
rts
WriteFormat: movem.l d2-d3/a2-a3/a6,-(sp)
movem.l a0-a2,-(sp) ; stack arguments
move.l #512,d0 ; MAXIMUM OUTPUT SIZE!!!!
moveq #MEMF_PUBLIC,d1
move.l (_SysBase).w,a6
libcall AllocMem ; allocate buffer
move.l d0,-(sp) ; stack buffer
bne.s MemOK
lea.l 16(sp),sp ; reset stack
moveq #-1,d0 ; -1 for error
bra.s FmtDone
MemOK: move.l (sp),a3 ; buffer to a3
move.l 8(sp),a0 ; format string to a0
move.l 12(sp),a1 ; arguments (pointer!) to a1
move.l #DoBuf,a2 ; special routine (support.s)
libcall RawDoFmt ; format the output
move.l (sp),a0 ; buffer to a0
bsr StrLen ; get the length
move.l d0,d3 ; put it in d3
move.l 4(sp),d1 ; handle to d1
move.l (sp),d2 ; buffer to d2
move.l _DOSBase,a6
libcall Write ; write it to the handle
move.l (sp)+,a1 ; buffer to a1
move.l d0,-(sp) ; stack Write return code
move.l #512,d0
move.l (_SysBase).w,a6
libcall FreeMem ; free the buffer
move.l (sp)+,d0 ; pull Write return code
lea.l 12(sp),sp ; reset the stack
FmtDone: movem.l (sp)+,d2-d3/a2-a3/a6
rts
MatchPattern: move.l d0,-(sp)
movem.l a0-a1,-(sp) ; push arguments
bsr Match ; call Match
lea.l 12(sp),sp ; restore stack
rts
*
* this is the actual pattern matching routine. It expects the parrameters
* on the stack. It call's itself several times. recursive, needs some stack!
*
Match: movem.l a2-a3/a5/d2,-(sp)
move.l 20(sp),a2 ; str = a2
move.l 24(sp),a3 ; pat = a3
move.l 28(sp),d2 ; case flag
move.l a3,a0 ; a0 = pat
bsr StrLen ; strlen(a0)
tst.l d0 ; len == 0 ?
bne.s FOREVER ; no, there is a pattern
moveq #1,d0 ; always return TRUE when no
bra.s TheEnd ; pattern is found.
FOREVER: move.b (a2),d0 ; d0 = *str
tst.l d2 ; case check true ?
bne.s NotLow ; no
bsr ToLower ; tolower(d0)
NotLow: move.b d0,d1 ; d1 = d0
move.b (a3),d0 ; d0 = *pat
tst.l d2 ; case check true ?
bne.s NotLow1 ; no
bsr ToLower ; tolower(d0)
NotLow1: cmp.b d0,d1 ; d0 == d1 ?
bne.s NotSameChar ; no.. check for WildCards
tst.b (a2)+ ; *str++ == 0 ?
bne.s AddPat ; no..
moveq #1,d0 ; TRUE
TheEnd: movem.l (sp)+,a2-a3/a5/d2
rts ; return
AddPat: inc.w a3 ; pat++
bra.s FOREVER ; loop
NotSameChar: cmp.b #'?',(a3) ; *pat == '?' ?
bne.s Artis ; no..
tst.b (a2) ; *str == 0 ?
beq.s Artis ; yes..
inc.w a3 ; pat++
inc.w a2 ; str++
bra.s FOREVER
Artis: cmp.b #'*',(a3) ; *pat == '*' ?
beq.s IsArt ; yes..
cldat d0 ; FALSE
bra.s TheEnd ; return
IsArt: cmp.b #'*',(a3) ; *pat == '*' ?
bne.s DoAgain ; no..
inc.w a3
tst.b (a3) ; *++pat == 0 ?
bne.s IsArt ; no.. loop
moveq #1,d0 ; TRUE
bra.s TheEnd ; return
DoAgain: move.l a2,a0 ; a0 = str
bsr StrLen ; strlen(a0)
move.l d0,a5 ; a5 = len
add.l a2,a5 ; a5 += str
dec.w a5 ; a5--
bra.s CheckEnd1 ; check if all are done
LoopIt: move.b (a5),d0 ; d0 = *a5
tst.l d2 ; check case flag
bne.s DoCase ; yes.. check the case
bsr ToLower ; make lower case
DoCase: move.b d0,d1 ; put char in d1
move.b (a3),d0 ; d0 == *pat
tst.l d2 ; check case flag
bne.s DoCase2 ; yes.. check the case
bsr ToLower ; make lower case
DoCase2: cmp.b d0,d1 ; compare to chars
bne.s CheckEnd ; check if all are done
move.l d2,-(sp) ; push case flag
move.l a3,-(sp) ; push pat
move.l a5,-(sp) ; push a5
bsr Match ; Match(a5,a3,d2)
lea 12(sp),sp ; reset the stack
tst.l d0 ; d0 == 0 ?
beq.s CheckEnd ; yes.. check if all are done
moveq #1,d0 ; TRUE
bra TheEnd ; return
CheckEnd: dec.w a5 ; a5--
CheckEnd1: cmp.l a2,a5 ; a5 >= str
bcc.s LoopIt ; yes loop
cldat d0 ; FALSE
bra TheEnd ; return
Isolate: movem.l a2-a3/a6,-(sp)
move.l a0,a2 ; fp = a2
move.l a1,a3 ; b = a3
move.b #'/',d0
move.l a2,a0
bsr CharRight ; charright(fp,'/')
tst.l d0 ; found ?
bne.s FoundChar ; yes..
move.b #':',d0
move.l a2,a0
bsr CharLeft ; charleft(fp,':')
tst.l d0 ; found ?
bne.s FoundChar ; yes..
move.b #'*',d0
move.l a2,a0
bsr CharRight ; charright(fp,'*')
tst.l d0 ; found ?
bne.s DoCopy ; yes..
move.b #'?',d0
move.l a2,a0
bsr CharRight ; charright(fp,'?')
tst.l d0 ; found ?
beq.s NoCopy ; no..
DoCopy: move.l a3,a0 ; dest = b
move.l a2,a1 ; source = fp
bsr StrCpy ; StrCpy(b,fp)
clr.b (a2) ; fp[0] = 0
moveq #1,d0 ; TRUE
bra.s EndIso ; return
NoCopy: clr.b (a3) ; b[0] = 0
cldat d0 ; FALSE
bra.s EndIso ; return
FoundChar: move.l d0,a6 ; adr to a6
move.b #'*',d0
move.l a6,a0
bsr CharLeft ; charleft(adr,'*')
tst.l d0 ; found ?
bne.s GotWild ; yes..
move.b #'?',d0
move.l a2,a0
bsr CharRight ; charright(fp,'?')
tst.l d0 ; found ?
beq.s NoWild ; no..
GotWild: inc.w a6 ; adr++
move.l a3,a0 ; dest = b
move.l a6,a1 ; source = adr
bsr StrCpy ; StrCpy(dest,source)
clr.b (a6) ; adr[1] = 0
moveq #1,d0 ; TRUE
bra.s EndIso ; return
NoWild: clr.b (a3) ; b[0] = 0
cldat d0 ; FALSE
EndIso: movem.l (sp)+,a2-a3/a6
rts ; return
BstrToCstr: add.l a0,a0
add.l a0,a0 ; BADDR(bstr)
cldat d0
move.b (a0)+,d0 ; size = bstr[0]
bra.s Begin ; begin loop
Copy: move.b (a0)+,(a1)+ ; buf[i-1] = bstr[i]
Begin: dbra d0,Copy ; loop until size bytes copied
clr.b (a1) ; buf[size] = 0
rts ; return
GetDate: movem.l d2-d7/a2-a3/a5-a6,-(sp)
move.l d0,-(sp)
movem.l a0-a1,-(sp)
moveq #ds_SIZEOF,d0 ; sizeof(struct DateStamp)
moveq #MEMF_PUBLIC,d1 ; MEMF_PUBLIC
move.l (_SysBase).w,a6
libcall AllocMem ; AllocMem(ds_SIZEOF,MEMF_PUBLIC)
move.l d0,a2 ; pointer to a2
bne.s AllocOK ; if NULL allocation failed
moveq #0,d0 ; FALSE
bra AllocFailed ; return
AllocOK: move.l 4(sp),a3 ; buffer pointer to a3
tst.l (sp) ; passed a DateStamp ?
beq.s StampIt ; no.. system time
move.l (sp),a0 ; your stamp as source
moveq #2,d0
Doit: move.l (a0)+,(a2)+
dbra d0,Doit
sub.l #12,a2
bra.s Copied
StampIt: move.l a2,d1 ; buffer to d1
move.l _DOSBase,a6
libcall DateStamp ; DateStamp(buffer)
Copied: move.l ds_Days(a2),d4 ; days to d4
move.l ds_Minute(a2),d0 ; minutes to d0
divu #60,d0 ; devide by 60
move.w d0,d5 ; low 16 bits is hours
ext.l d5 ; long extension
swap d0 ; high 16 bits is remainder (minutes)
move.w d0,d6 ; to d6
ext.l d6 ; long extension
move.l ds_Tick(a2),d0 ; ticks to d0
divu #TICKS_PER_SECOND,d0 ; devide by TICKS_PER_SECOND
move.w d0,d7 ; low 16 bits is seconds
ext.l d7 ; long extension
tst.l d4 ; days < 0
blt.s ScrewedUp ; if so, error
tst.l d6 ; mins < 0
blt.s ScrewedUp ; if so, error
tst.l d7 ; secs < 0
bge.s DateOK ; if not, OK
ScrewedUp: pea su ; copy error string
move.l a3,-(sp) ; into your buffer
jsr DoFmt
addq.w #8,sp ; reset stack
moveq #0,d0 ; FALSE
bra EndGD ; return
DateOK: inc.l d4 ; days++
move.l #1978,d2 ; start at 1978
YearLoop: move.l d2,d0 ; year to d0
divu #4,d0 ; devide by 4
swap d0 ; swap for remainder
tst.w d0 ; is there a remainder ?
bne.s NotLeap ; yes.. it's no leap year
move.l #366,d1 ; 366 days in a leap year
bra.s CheckDays
NotLeap: move.l #365,d1 ; 365 days in a normal year
CheckDays: cmp.l d1,d4 ; days <= dayes_per_year
ble.s EndYear ; yes.. break
sub.l d1,d4 ; days -= dayes_per_year
inc.l d2 ; year++
bra.s YearLoop ; loop
EndYear: cldat d3 ; mon = 0
MonLoop: cmp.l #12,d3 ; mon <= 12
bgt.s EndMon ; no.. break
lea.l dim,a0 ; dayes_in_month table to a0
move.l d3,d0 ; mon to d0
add.l d0,d0 ; d0 * 2 for correct table offset
move.w (a0,d0.l),d1 ; dpm = dayes_per_month[mon]
ext.l d1 ; long extension
cmp.l #1,d3 ; is mon 1 ?
bne.s NotFeb ; no not february
move.l d2,d0 ; year to d0
divu #4,d0 ; devide by four
swap d0 ; swap for remainder
tst.w d0 ; is there a remainder ?
bne.s NotFeb ; yes.. it's not a leap year
inc.l d1 ; else february has 29 days
NotFeb: cmp.l d1,d4 ; days <= dpm
ble.s EndMon ; yes.. break
sub.l d1,d4 ; days -= dpm
inc.l d3 ; mon++
bra.s MonLoop ; loop
EndMon: move.l ds_Days(a2),d0 ; days to d0
divu #7,d0 ; devide by 7
swap d0 ; swap for remaider
ext.l d0 ; long extension
asl.l #2,d0 ; d0 * 4 for correct table offset
lea dys,a0 ; days table to a0
move.l (a0,d0.l),a6 ; a6 = dayes[d0]
lea.l mnt,a0 ; month table to a0
asl.l #2,d3 ; d3 * 4 for correct table offset
move.l (a0,d3.l),a5 ; a5 = month[d3]
cmp.l #ONLY_DAY,8(sp) ; do you want only the day ?
bne.s Date ; no.. branch
move.l a6,-(sp) ; push day
pea j1 ; push format string
move.l a3,-(sp) ; push buffer
bsr DoFmt ; format the output
lea.l 12(sp),sp ; reset stack
bra.s Done ; return
Date: cmp.l #ONLY_DATE,8(sp) ; do you want only the date ?
bne.s Time ; no.. branch
move.l d2,-(sp) ; push year
move.l a5,-(sp) ; push month
move.l d4,-(sp) ; push day
pea j2 ; push format string
move.l a3,-(sp) ; push buffer
bsr DoFmt ; format the output
lea.l 20(sp),sp ; reset stack
bra.s Done ; return
Time: cmp.l #ONLY_TIME,8(sp) ; do you want only the time ?
bne.s All ; no branch
move.l d7,-(sp) ; push second
move.l d6,-(sp) ; push minute
move.l d5,-(sp) ; push hours
pea j3 ; push format string
move.l a3,-(sp) ; push buffer
bsr DoFmt ; format the output
lea.l 20(sp),sp ; reset stack
bra.s Done ; return
All: move.l d7,-(sp) ; push second
move.l d6,-(sp) ; push minute
move.l d5,-(sp) ; push hour
move.l d2,-(sp) ; push year
move.l a5,-(sp) ; push month
move.l d4,-(sp) ; push day
move.l a6,-(sp) ; push ascii day
pea j4 ; push format string
move.l a3,-(sp) ; push buffer
bsr DoFmt ; format the output
lea.l 36(sp),sp ; reset the stack
Done: moveq #1,d0 ; TRUE
EndGD: move.l d0,-(sp) ; push return code
move.l a2,a1 ; date buffer to a1
moveq #ds_SIZEOF,d0 ; sizeof(struct DateStamp)
move.l (_SysBase).w,a6
libcall FreeMem ; FreeMem(dbuf,ds_SIZEOF)
move.l (sp)+,d0 ; pull return code
AllocFailed: lea.l 12(sp),sp
movem.l (sp)+,d2-d7/a2/a3/a5/a6
rts ; return
even
dim: dc.w 31,28,31,30,31,30,31,31,30,31,30,31
mnt: dc.l s+0,s+4,s+8,s+12,s+16,s+20,s+24,s+28,s+32,s+36,s+40,s+44
dys: dc.l s+48,s+55,s+62,s+70,s+80,s+89,s+96
even
s: dc.b 'Jan',0,'Feb',0,'Mar',0,'Apr',0,'May',0,'Jun',0
dc.b 'Jul',0,'Aug',0,'Sep',0,'Oct',0,'Nov',0,'Dec',0
dc.b 'Sunday',0,'Monday',0,'Tuesday',0,'Wednesday',0
dc.b 'Thursday',0,'Friday',0,'Saterday',0
su: dc.b 'Date screwed up !',0
even
j1: dc.b '%-9ls',0
j2: dc.b '%02.2ld-%3ls-%04.4ld',0
j3: dc.b '%02.2ld:%02.2ld:%02.2ld',0
j4: dc.b '%-9ls %02.2ld-%3ls-%04.4ld %02.2ld:%02.2ld:%02.2ld',0
even